home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#05 (Dec85-Jan86)
/
modula2
/
serial ports 2-1
/
HackTerm.MOD
< prev
next >
Wrap
Text File
|
1985-11-23
|
4KB
|
163 lines
MODULE HackTerm;
(* Written by Jeff Mitchell
Digital Solutions, 1985
This is a simple terminal emulator
which completely bypasses the operating
system for serial I/O. *)
FROM Terminal IMPORT BusyRead,Write,WriteLn,
WriteString,ClearScreen;
FROM InOut IMPORT ReadInt;
CONST
(* Offsets into SCC registers *)
(* A channel is the modem port *)
aData = 6; (* A channel data *)
aCtl = 2; (* A channel control *)
(* B channel is the printer port *)
bData = 4; (* B channel data *)
bCtl = 0; (* B channel control *)
cntl_B = 2; (* ASCII value *)
cntl_C = 3; (* ASCII value *)
NULL = 0; (* ASCII value *)
TYPE
SerPtr = POINTER TO ARRAY [0..6] OF CHAR;
(* Needed for byte access *)
VAR
SCCRd [1D8H]: SerPtr; (* Read pointer *)
SCCWr [1DCH]: SerPtr; (* Write pointer *)
ch,status: CHAR;
bRate: INTEGER;
hiByte,loByte: CARDINAL;
PROCEDURE GetChar (VAR ch: CHAR): BOOLEAN;
(* Checks to see if a character has been
received and fetches it *)
BEGIN
SCCWr^[aCtl]:= CHR(0); (* Tx, Rx status *)
status:= SCCRd^[aCtl];
IF ODD(ORD(status)) THEN (* Test bit 0 *)
ch:= SCCRd^[aData]; (* Rx char available *)
RETURN TRUE
ELSE
RETURN FALSE (* No char received *)
END
END GetChar;
PROCEDURE PutChar (VAR ch: CHAR);
(* Waits until transmit buffer empty then
outputs a character. *)
BEGIN
REPEAT (* Wait until xmit buffer empty *)
SCCWr^[aCtl]:= CHR(0); (* Tx, Rx status *)
status:= SCCRd^[aCtl]
UNTIL ODD(ORD(status) DIV 4); (* Test bit 2 *)
SCCWr^[aData]:= ch (* transmit char *)
END PutChar;
PROCEDURE SetBaud;
(* Compute the time constant for the baud
rate generator and split it into high
and low bytes. *)
BEGIN
WriteLn;
WriteString('Desired baud rate? ');
ReadInt(bRate);
WriteLn;
(* Compute baud rate generator time constants *)
hiByte:= (TRUNC(115000.0 / FLOAT(CARDINAL(bRate))) - 2) DIV 256;
loByte:= (TRUNC(115000.0 / FLOAT(CARDINAL(bRate))) - 2) MOD 256;
SCCWr^[aCtl]:= CHR(13);
SCCWr^[aCtl]:= CHR(hiByte);
SCCWr^[aCtl]:= CHR(12);
SCCWr^[aCtl]:= CHR(loByte)
END SetBaud;
BEGIN (* HackTerm *)
ClearScreen;
ch:= SCCRd^[aCtl]; (* Ensure ptr reg = 0 *)
(* Reset channel A, enable all interrupts *)
SCCWr^[aCtl]:= CHR(9);
SCCWr^[aCtl]:= CHR(136);
(* Enable external status interrupts *)
SCCWr^[aCtl]:= CHR(1);
SCCWr^[aCtl]:= CHR(1);
(* Set Tx, Rx modes *)
SCCWr^[aCtl]:= CHR(4);
SCCWr^[aCtl]:= CHR(76);
(* Set clock mode *)
SCCWr^[aCtl]:= CHR(11);
SCCWr^[aCtl]:= CHR(80);
(* Set default baud rate to 300 *)
(* Lower byte *)
SCCWr^[aCtl]:= CHR(12);
SCCWr^[aCtl]:= CHR(124);
(* Upper byte *)
SCCWr^[aCtl]:= CHR(13);
SCCWr^[aCtl]:= CHR(1);
(* Enable baud rate generator *)
SCCWr^[aCtl]:= CHR(14);
SCCWr^[aCtl]:= CHR(1);
(* Enable DCD (mouse) interrupts *)
SCCWr^[aCtl]:= CHR(15);
SCCWr^[aCtl]:= CHR(8);
(* Set Rx parameters, enable receiver *)
SCCWr^[aCtl]:= CHR(3);
SCCWr^[aCtl]:= CHR(193);
(* Set Tx parameters, enable transmitter *)
SCCWr^[aCtl]:= CHR(5);
SCCWr^[aCtl]:= CHR(106);
BusyRead(ch);
IF ORD(ch) <> cntl_C THEN
REPEAT
IF ORD(ch) = cntl_B THEN
SetBaud
ELSE
IF ORD(ch) <> NULL THEN
PutChar(ch)
END
END;
WHILE GetChar(ch) DO
Write(ch)
END;
BusyRead(ch);
UNTIL ORD(ch) = cntl_C
END
END HackTerm.